package com.api_gateway.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/debug")
public class GatewayDebugController {
    
    @Autowired(required = false)
    private RouteLocator routeLocator;
    
    @Autowired
    private DiscoveryClient discoveryClient;
    
    @GetMapping("/routes")
    public Mono<Map<String, Object>> getRoutes() {
        Map<String, Object> result = new HashMap<>();
        result.put("routeLocatorAvailable", routeLocator != null);
        
        if (routeLocator != null) {
            return routeLocator.getRoutes()
                .collectList()
                .map(routes -> {
                    result.put("timestamp", System.currentTimeMillis());
                    result.put("routeCount", routes.size());
                    result.put("routes", routes.stream()
                        .map(route -> Map.of(
                            "id", route.getId(),
                            "uri", route.getUri().toString()
                        ))
                        .collect(Collectors.toList()));
                    return result;
                });
        } else {
            result.put("error", "RouteLocator is not available - Gateway may not be properly configured");
            result.put("timestamp", System.currentTimeMillis());
            return Mono.just(result);
        }
    }
    
    @GetMapping("/services")
    public Map<String, Object> getAllServices() {
        Map<String, Object> result = new HashMap<>();
        List<String> services = discoveryClient.getServices();
        result.put("serviceCount", services.size());
        result.put("services", services);
        
        Map<String, Object> serviceDetails = new HashMap<>();
        for (String service : services) {
            List<ServiceInstance> instances = discoveryClient.getInstances(service);
            serviceDetails.put(service, instances.stream().map(instance -> 
                Map.of(
                    "host", instance.getHost(),
                    "port", instance.getPort(),
                    "uri", instance.getUri()
                )
            ).collect(Collectors.toList()));
        }
        result.put("serviceDetails", serviceDetails);
        
        return result;
    }
    
    @GetMapping("/test/{service}")
    public Mono<Map<String, Object>> testService(@PathVariable String service) {
        WebClient client = WebClient.create();
        return client.get()
            .uri("http://localhost:8848/nacos/v1/ns/instance/list?serviceName=" + service)
            .retrieve()
            .bodyToMono(Map.class)
            .map(health -> Map.of(
                "service", service,
                "health", health,
                "testedAt", System.currentTimeMillis()
            ))
            .onErrorResume(e -> Mono.just(Map.of(
                "service", service,
                "error", e.getMessage(),
                "testedAt", System.currentTimeMillis()
            )));
    }
}